#if !defined(_TYPEDESCRIPTOR_H)
#define _TYPEDESCRIPTOR_H

#include "Utility.h"
#include "alias.h"
#include "boost/enable_shared_from_this.hpp"

CREATE_ALIAS( TypeDescriptor );
CREATE_MAP_ALIAS( TypeDescriptor );

/**
 * Class used to store a type descriptor.
 */
class DECLARATION_DLL TypeDescriptor : public enable_shared_from_this<TypeDescriptor>
{
	protected:
		
		/** Name of the plugin where this type is defined. */
		string pluginName;

		/** Name of the type (this is not the fully qualified name). */
		string name;

		/** Description of the type */
		string description;

	public:
		
		/**
		 * Create a type descriptor.
		 */
		TypeDescriptor(string pluginName, string name, string description)
		{
			this->pluginName = pluginName;
			this->name = name;
			this->description = description;
		}

		/**
		* Get the name of the plugin where this type is defined.
		*/
		virtual string GetPluginName()
		{
			return pluginName;
		}

		/**
		 * Get the name of this type.
		 */
		virtual string GetName()
		{
			return name;
		}

		/**
		* Get the fully qualified name of this type.
		*/
		virtual string GetFullyQualifiedName()
		{
			return Utility::GetFullyQualifiedName(pluginName, name);
		}

		/**
		 * Get the description of the type.
		 */
		virtual string GetDescription()
		{
			return description;
		}

		/**
		 * True if the type descriptor is valid.
		 */
		virtual bool IsValid()
		{
			return true;
		}

		/**
		 * True if the type descriptor describe the complex type specified.
		 */
		virtual bool Describe(SType type) = 0;

		/**
 		 * Returns the complex type described from this type descriptor
		 */
		virtual SType GetDescribedType() = 0;

		/**
		 * Very useful template function to convert a TypeDescriptorSp to a subclass.
		 */ 
		template <typename T>
		shared_ptr<T> As()
		{
			return dynamic_pointer_cast<T, TypeDescriptor>(shared_from_this());
		}

};

#endif  //_TYPEDESCRIPTOR_H
